﻿//======================================================================
//
//        Copyright : Zhengzhou Strawberry Computer Technology Co.,LTD.
//        All rights reserved
//
//        Application:NFinal MVC framework
//        Filename :SqlCompiler.cs
//        Description :csharp魔法函数语句分析和编译类
//
//        created by Lucas at  2015-6-30`
//     
//        WebSite:http://www.nfinal.com
//
//======================================================================
using System;
using System.Collections.Generic;
using System.Web;
using System.Text.RegularExpressions;

namespace NFinal.Compile
{

    /// <summary>
    /// csharp魔法函数语句分析和编译类
    /// </summary>
    public class SqlCompiler
    {
        private static Regex dbFuncitonRegex = new Regex(@"(?:(\S+)\s+)?(\S+)\s*=\s*Models\s*.\s*([^\s\.]+)\s*.\s*([^\s\.]+)\s*\(\s*(?:@?""([^""]*)""(?:,\s*([^\s,\)]+))?)?\s*\)(?:\s*.\s*([^\(\)\s;.]+)\s*\(\s*\))?\s*;");
        public SqlCompiler()
        {
        }
        /// <summary>
        /// 分析代码
        /// </summary>
        /// <param name="csharpCode">代码</param>
        /// <param name="index">代码开始的位置</param>
        /// <returns></returns>
        public System.Collections.Generic.List<DbFunctionData> Compile(string csharpCode)
        {
            //找出所有的Connection对象
            System.Collections.Generic.List<SqlConnection> sqlConnectionList = SqlConnection.GetSqlConnectionList(csharpCode);
            //找出所有的Trasaction对象
            System.Collections.Generic.List<SqlTransaction> sqlTransactionList = SqlTransaction.GetSqlTransactionList(csharpCode, sqlConnectionList);
            #region 找出所有的Connection与Trasaction执行的sql语句
            System.Collections.Generic.List<DbFunctionData> dbFunctionDataList = new System.Collections.Generic.List<DbFunctionData>();
            DbFunctionData dbFunctionData;
            string dbFunctionDataRegexStr= @"(?:([^{};\s]+)\s+)?(\S+)\s*=\s*(\S+)\s*.\s*(QueryRandom|QueryAll|QueryTop|Page|QueryRow|QueryObject|Insert|Update|Delete|ExecuteNonQuery)\s*(?:<\s*(\S+)\s*>\s*)?\(\s*(\$)?""([^""]*)""(?:,\s*([^\s,\)]+))?\s*\)\s*(\.\s*(ToByte|ToSByte|ToChar|ToDateTime|ToDecimal|ToDouble|ToSingle|ToBoolean|ToInt16|ToInt32|ToInt64|ToUInt16|ToUInt32|ToUInt64)\s*\(\s*\)\s*)?;";
            Regex dbFunctionDataRegex = new Regex(dbFunctionDataRegexStr);
            MatchCollection dbFunctionDataMac = dbFunctionDataRegex.Matches(csharpCode);
            for (int i = 0; i < dbFunctionDataMac.Count; i++)
            {
                if(dbFunctionDataMac[i].Success)
                {
                    dbFunctionData = new DbFunctionData();
                    dbFunctionData.expression = dbFunctionDataMac[i].Groups[0].Value;
                    dbFunctionData.type = dbFunctionDataMac[i].Groups[1].Value;
                    if (dbFunctionDataMac[i].Groups[1].Success)
                    {
                        dbFunctionData.isDeclaration = true;
                    }
                    dbFunctionData.varName = dbFunctionDataMac[i].Groups[2].Value;
                    
                    dbFunctionData.connectionVarName = dbFunctionDataMac[i].Groups[3].Value;
                    for (int j = 0; j < sqlConnectionList.Count; j++)
                    {
                        if (sqlConnectionList[j].varName == dbFunctionData.connectionVarName)
                        {
                            dbFunctionData.connectionName = sqlConnectionList[j].connectionName;
                            dbFunctionData.isTransaction = false;
                            break;
                        }
                    }
                    dbFunctionData.transactionVarName = dbFunctionDataMac[i].Groups[3].Value;
                    for (int j = 0; j < sqlTransactionList.Count; j++)
                    {
                        if (sqlTransactionList[j].varName == dbFunctionData.transactionVarName)
                        {
                            dbFunctionData.connectionVarName = sqlConnectionList[j].varName;
                            dbFunctionData.connectionName = sqlConnectionList[j].connectionName;
                            dbFunctionData.isTransaction = true;
                            break;
                        }
                    }
                    dbFunctionData.functionName = dbFunctionDataMac[i].Groups[4].Value;
                    dbFunctionData.hasGenericType = dbFunctionDataMac[i].Groups[5].Success;
                    if (dbFunctionData.hasGenericType)
                    {
                        dbFunctionData.type = dbFunctionDataMac[i].Groups[5].Value;
                    }
                    dbFunctionData.isSuperString = dbFunctionDataMac[i].Groups[6].Success;
                    if (dbFunctionData.isSuperString)
                    {
                        dbFunctionData.sql = dbFunctionDataMac[i].Groups[7].Value.Replace("{","").Replace("}","");
                    }
                    else
                    {
                        dbFunctionData.sql = dbFunctionDataMac[i].Groups[7].Value;
                    }
                    if (dbFunctionDataMac[i].Groups[8].Success)
                    {
                        dbFunctionData.parameters = new string[2];
                        //select sql
                        dbFunctionData.parameters[0] = dbFunctionDataMac[i].Groups[7].Value;
                        //pageSize
                        dbFunctionData.parameters[1] = dbFunctionDataMac[i].Groups[8].Value;
                    }
                    else
                    {
                        dbFunctionData.parameters = new string[1];
                        dbFunctionData.parameters[0] = dbFunctionDataMac[i].Groups[7].Value;
                    }
                    dbFunctionData.convertMethodName = dbFunctionDataMac[i].Groups[9].Value;
                    dbFunctionData.index = dbFunctionDataMac[i].Index;
                    dbFunctionData.length = dbFunctionDataMac[i].Length;
                    //如果没有标识类型，则默认填充类型
                    if (!dbFunctionData.hasGenericType)
                    {
                        if (dbFunctionData.functionName == "ExecuteNonQuery")
                        {
                            dbFunctionData.type = "int";
                        }
                        else if (dbFunctionData.functionName == "Insert")
                        {
                            dbFunctionData.type = "int";
                        }
                        else if (dbFunctionData.functionName == "QueryObject")
                        {
                            dbFunctionData.type = "object";
                        }
                        else if (dbFunctionData.functionName == "Delete")
                        {
                            dbFunctionData.type = "int";
                        }
                        else if (dbFunctionData.functionName == "Update")
                        {
                            dbFunctionData.type = "int";
                        }
                    }
                    dbFunctionDataList.Add(dbFunctionData);
                }
            }
            #endregion
            return dbFunctionDataList;
        }
        //在某段位置替换成另一段代码
        public int Replace(ref string str, int index, int length, string rep)
        {
            if (length > 0)
            {
                str = str.Remove(index, length);
            }
            if (index > 0)
            {
                str = str.Insert(index, rep);
            }
            return rep.Length - length;
        }
        private DB.ConnectionString GetConnectionString(string name)
        {
            if (Frame.ConnectionStrings.Count > 0)
            {
                for (int i = 0; i < Frame.ConnectionStrings.Count; i++)
                {
                    if (Frame.ConnectionStrings[i].name == name)
                    {
                        return Frame.ConnectionStrings[i];
                    }
                }
                return null;
            }
            else
            {
                return null;
            }
        }
        public int SetMagicConnection(string methodName, ref string csharpCode, string appRoot)
        {
            if (methodName == "queryAll")
            {

            }
            System.Collections.Generic.List<SqlConnection> sqlConnectionList = SqlConnection.GetSqlConnectionList(csharpCode);
            DB.ConnectionString connectionString = null;
            string fileString = null;
            JinianNet.JNTemplate.ITemplate template = null;
            string conCode = null;
            int relative_position = 0;
            for (int i=0;i<sqlConnectionList.Count;i++)
            {
                connectionString = GetConnectionString(sqlConnectionList[i].connectionName);
                if (sqlConnectionList[i].isGet)
                {
                    //conCode = string.Empty;
                    if (connectionString.type == DB.DBType.MySql)
                    {
                        conCode = string.Format("var {0}=(MySql.Data.MySqlClient.MySqlConnection){1};", sqlConnectionList[i].varName, sqlConnectionList[i].parName);
                    }
                    else if (connectionString.type == DB.DBType.Oracle)
                    {
                        conCode = string.Format("var {0}=(Oracle.ManagedDataAccess.Client.OracleConnection){1};", sqlConnectionList[i].varName, sqlConnectionList[i].parName);
                    }
                    else if (connectionString.type == DB.DBType.Sqlite)
                    {
                        conCode = string.Format("var {0}=(System.Data.SQLite.SQLiteConnection){1};", sqlConnectionList[i].varName, sqlConnectionList[i].parName);
                    }
                    else if (connectionString.type == DB.DBType.SqlServer)
                    {
                        conCode = string.Format("var {0}=(System.Data.SqlClient.SqlConnection){1};", sqlConnectionList[i].varName, sqlConnectionList[i].parName);
                    }
                    else if (connectionString.type == DB.DBType.PostgreSql)
                    {
                        conCode = string.Format("var {0}=(Npgsql.NpgsqlConnection){1};", sqlConnectionList[i].varName, sqlConnectionList[i].parName);
                    }
                }
                else
                {
                    if (connectionString.type == DB.DBType.MySql)
                    {
                        fileString = NFinal.Compile.SqlTemplate.mysql.mysql.Open;
                    }
                    else if (connectionString.type == DB.DBType.Oracle)
                    {
                        fileString = NFinal.Compile.SqlTemplate.oracle.oracle.Open;
                    }
                    else if (connectionString.type == DB.DBType.Sqlite)
                    {
                        fileString = NFinal.Compile.SqlTemplate.sqlite.sqlite.Open;
                    }
                    else if (connectionString.type == DB.DBType.SqlServer)
                    {
                        fileString = NFinal.Compile.SqlTemplate.sqlserver.sqlserver.Open;
                    }
                    else if(connectionString.type==DB.DBType.PostgreSql)
                    {
                        fileString = NFinal.Compile.SqlTemplate.postgresql.postgresql.Open;
                    }
                    template = new JinianNet.JNTemplate.Template(fileString);
                    template.Context.TempData["functionName"] = methodName;
                    template.Context.TempData["connectionVarName"] = sqlConnectionList[i].varName;
                    template.Context.TempData["dbName"] = sqlConnectionList[i].connectionName;
                    conCode = template.Render();
                }
                relative_position += Replace(ref csharpCode, sqlConnectionList[i].index + relative_position, sqlConnectionList[i].length, conCode);
            }
            return relative_position;
        }
        /// <summary>
        /// 执行数据库魔法函数
        /// </summary>
        /// <param name="methodName">Controller的函数名</param>
        /// <param name="csharpFileCode">Controller的函数内的代码</param>
        /// <param name="dbFunctionDatas">代码内分析出的魔法函数</param>
        /// <param name="appRoot">项目的根目录</param>
        /// <returns></returns>
        public int SetMagicFunction(string methodName, ref string csharpFileCode, int relative_position, System.Collections.Generic.List<DbFunctionData> dbFunctionDatas,string appRoot)
        {
            if(dbFunctionDatas.Count>0)
            {
                string webCsharpCode = "";
                //VTemplate.Engine.TemplateDocument doc=null;
                JinianNet.JNTemplate.ITemplate tempalte = null;
                DB.ConnectionString connectionString=null;
                //string fileName = null;
 
                for (int i = 0; i < dbFunctionDatas.Count; i++)
                {
                    connectionString= GetConnectionString(dbFunctionDatas[i].connectionName);
                    if(connectionString!=null)
                    {
                        if (dbFunctionDatas[i].functionName == "ExecuteNonQuery")
                        {
                            string fileString = null;
                            if (connectionString.type == DB.DBType.MySql)
                            {
                                fileString =NFinal.Compile.SqlTemplate.mysql.mysql.ExecuteNonQuery;
                            }
                            else if(connectionString.type ==DB.DBType.Oracle)
                            {
                                fileString = NFinal.Compile.SqlTemplate.oracle.oracle.ExecuteNonQuery;
                            }
                            else if (connectionString.type == DB.DBType.Sqlite)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlite.sqlite.ExecuteNonQuery;
                            }
                            else if (connectionString.type == DB.DBType.SqlServer)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlserver.sqlserver.ExecuteNonQuery;
                            }
                            else if(connectionString.type == DB.DBType.PostgreSql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.postgresql.postgresql.ExecuteNonQuery;
                            }
                            tempalte = new JinianNet.JNTemplate.Template(fileString);
                            tempalte.Context.TempData["functionName"] = methodName;
                            tempalte.Context.TempData["varName"] = dbFunctionDatas[i].varName;
                            tempalte.Context.TempData["hasGenericType"] = dbFunctionDatas[i].hasGenericType;
                            tempalte.Context.TempData["type"] = dbFunctionDatas[i].type;
                            tempalte.Context.TempData["isDeclaration"] = dbFunctionDatas[i].isDeclaration;
                            tempalte.Context.TempData["connectionVarName"] = dbFunctionDatas[i].connectionVarName;
                            tempalte.Context.TempData["isTransaction"] = dbFunctionDatas[i].isTransaction;
                            tempalte.Context.TempData["transactionVarName"] = dbFunctionDatas[i].transactionVarName;
                            tempalte.Context.TempData["dbName"] = dbFunctionDatas[i].connectionName;
                            tempalte.Context.TempData["sql"] = dbFunctionDatas[i].sql;
                            tempalte.Context.TempData["fields"] = dbFunctionDatas[i].fields;
                            tempalte.Context.TempData["sqlVarParameters"] = dbFunctionDatas[i].sqlVarParameters;
                            webCsharpCode = tempalte.Render();
                            relative_position += Replace(ref csharpFileCode,
                                relative_position + dbFunctionDatas[i].index,
                                dbFunctionDatas[i].length,
                                webCsharpCode);
                        }
                        if (dbFunctionDatas[i].functionName == "QueryAll")
                        {
                            string fileString = null;
                            if (connectionString.type == DB.DBType.MySql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.mysql.mysql.QueryAll;
                            }
                            else if (connectionString.type == DB.DBType.Oracle)
                            {
                                fileString = NFinal.Compile.SqlTemplate.oracle.oracle.QueryAll;
                            }
                            else if (connectionString.type == DB.DBType.Sqlite)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlite.sqlite.QueryAll;
                            }
                            else if (connectionString.type == DB.DBType.SqlServer)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlserver.sqlserver.QueryAll;
                            }
                            else if(connectionString.type == DB.DBType.PostgreSql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.postgresql.postgresql.QueryAll;
                            }
                            tempalte = new JinianNet.JNTemplate.Template(fileString);
                            tempalte.Context.TempData["functionName"] = methodName;
                            tempalte.Context.TempData["varName"] = dbFunctionDatas[i].varName;
                            tempalte.Context.TempData["hasGenericType"] = dbFunctionDatas[i].hasGenericType;
                            tempalte.Context.TempData["type"] = dbFunctionDatas[i].type;
                            tempalte.Context.TempData["isDeclaration"] = dbFunctionDatas[i].isDeclaration;
                            tempalte.Context.TempData["connectionVarName"] = dbFunctionDatas[i].connectionVarName;
                            tempalte.Context.TempData["isTransaction"] = dbFunctionDatas[i].isTransaction;
                            tempalte.Context.TempData["transactionVarName"] = dbFunctionDatas[i].transactionVarName;
                            tempalte.Context.TempData["dbName"] = dbFunctionDatas[i].connectionName;
                            tempalte.Context.TempData["sql"] = dbFunctionDatas[i].sql;
                            tempalte.Context.TempData["fields"] = dbFunctionDatas[i].fields;
                            tempalte.Context.TempData["sqlVarParameters"] = dbFunctionDatas[i].sqlVarParameters;
                            webCsharpCode = tempalte.Render();
                            relative_position += Replace(ref csharpFileCode,
                                relative_position + dbFunctionDatas[i].index,
                                dbFunctionDatas[i].length,
                                webCsharpCode);
                        }
                        if (dbFunctionDatas[i].functionName == "QueryRow")
                        {
                            string fileString = null;
                            if (connectionString.type == DB.DBType.MySql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.mysql.mysql.QueryRow;
                            }
                            else if (connectionString.type == DB.DBType.Oracle)
                            {
                                fileString = NFinal.Compile.SqlTemplate.oracle.oracle.QueryRow;
                            }
                            else if (connectionString.type == DB.DBType.Sqlite)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlite.sqlite.QueryRow;
                            }
                            else if (connectionString.type == DB.DBType.SqlServer)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlserver.sqlserver.QueryRow;
                            }
                            else if(connectionString.type == DB.DBType.PostgreSql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.postgresql.postgresql.QueryRow;
                            }
                            tempalte = new JinianNet.JNTemplate.Template(fileString);
                            tempalte.Context.TempData["functionName"] = methodName;
                            tempalte.Context.TempData["varName"] = dbFunctionDatas[i].varName;
                            tempalte.Context.TempData["hasGenericType"] = dbFunctionDatas[i].hasGenericType;
                            tempalte.Context.TempData["type"] = dbFunctionDatas[i].type;
                            tempalte.Context.TempData["isDeclaration"] = dbFunctionDatas[i].isDeclaration;
                            tempalte.Context.TempData["connectionVarName"] = dbFunctionDatas[i].connectionVarName;
                            tempalte.Context.TempData["isTransaction"] = dbFunctionDatas[i].isTransaction;
                            tempalte.Context.TempData["transactionVarName"] = dbFunctionDatas[i].transactionVarName;
                            tempalte.Context.TempData["dbName"] = dbFunctionDatas[i].connectionName;
                            tempalte.Context.TempData["sql"] = dbFunctionDatas[i].sql;
                            tempalte.Context.TempData["fields"] = dbFunctionDatas[i].fields;
                            tempalte.Context.TempData["sqlVarParameters"] = dbFunctionDatas[i].sqlVarParameters;
                            webCsharpCode = tempalte.Render();
                            relative_position += Replace(ref csharpFileCode,
                                relative_position + dbFunctionDatas[i].index,
                                dbFunctionDatas[i].length,
                                webCsharpCode);
                        }
                        if (dbFunctionDatas[i].functionName == "Insert")
                        {   
                            string fileString = null;
                            if (connectionString.type == DB.DBType.MySql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.mysql.mysql.Insert;
                            }
                            else if (connectionString.type == DB.DBType.Oracle)
                            {
                                fileString = NFinal.Compile.SqlTemplate.oracle.oracle.Insert;
                            }
                            else if (connectionString.type == DB.DBType.Sqlite)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlite.sqlite.Insert;
                            }
                            else if (connectionString.type == DB.DBType.SqlServer)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlserver.sqlserver.Insert;
                            }
                            else if(connectionString.type == DB.DBType.PostgreSql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.postgresql.postgresql.Insert;
                            }
                            tempalte = new JinianNet.JNTemplate.Template(fileString);
                            tempalte.Context.TempData["functionName"] = methodName;
                            tempalte.Context.TempData["varName"] = dbFunctionDatas[i].varName;
                            tempalte.Context.TempData["hasGenericType"] = dbFunctionDatas[i].hasGenericType;
                            tempalte.Context.TempData["type"] = dbFunctionDatas[i].type;
                            tempalte.Context.TempData["isDeclaration"] = dbFunctionDatas[i].isDeclaration;
                            tempalte.Context.TempData["connectionVarName"] = dbFunctionDatas[i].connectionVarName;
                            tempalte.Context.TempData["isTransaction"] = dbFunctionDatas[i].isTransaction;
                            tempalte.Context.TempData["transactionVarName"] = dbFunctionDatas[i].transactionVarName;
                            tempalte.Context.TempData["dbName"] = dbFunctionDatas[i].connectionName;
                            tempalte.Context.TempData["sql"] = dbFunctionDatas[i].sql;
                            tempalte.Context.TempData["tableName"] = dbFunctionDatas[i].tables[0].name;
                            tempalte.Context.TempData["fields"] = dbFunctionDatas[i].fields;
                            tempalte.Context.TempData["sqlVarParameters"] = dbFunctionDatas[i].sqlVarParameters;
                            webCsharpCode = tempalte.Render();
                            relative_position += Replace(ref csharpFileCode,
                                relative_position + dbFunctionDatas[i].index,
                                dbFunctionDatas[i].length,
                                webCsharpCode);

                        }
                        if (dbFunctionDatas[i].functionName == "Update")
                        {
                            string fileString = null;
                            if (connectionString.type == DB.DBType.MySql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.mysql.mysql.Update;
                            }
                            else if (connectionString.type == DB.DBType.Oracle)
                            {
                                fileString = NFinal.Compile.SqlTemplate.oracle.oracle.Update;
                            }
                            else if (connectionString.type == DB.DBType.Sqlite)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlite.sqlite.Update;
                            }
                            else if (connectionString.type == DB.DBType.SqlServer)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlserver.sqlserver.Update;
                            }
                            else if(connectionString.type == DB.DBType.PostgreSql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.postgresql.postgresql.Update;
                            }
                            tempalte = new JinianNet.JNTemplate.Template(fileString);
                            tempalte.Context.TempData["functionName"] = methodName;
                            tempalte.Context.TempData["varName"] = dbFunctionDatas[i].varName;
                            tempalte.Context.TempData["hasGenericType"] = dbFunctionDatas[i].hasGenericType;
                            tempalte.Context.TempData["type"] = dbFunctionDatas[i].type;
                            tempalte.Context.TempData["isDeclaration"] = dbFunctionDatas[i].isDeclaration;
                            tempalte.Context.TempData["connectionVarName"] = dbFunctionDatas[i].connectionVarName;
                            tempalte.Context.TempData["isTransaction"] = dbFunctionDatas[i].isTransaction;
                            tempalte.Context.TempData["transactionVarName"] = dbFunctionDatas[i].transactionVarName;
                            tempalte.Context.TempData["dbName"] = dbFunctionDatas[i].connectionName;
                            tempalte.Context.TempData["sql"] = dbFunctionDatas[i].sql;
                            tempalte.Context.TempData["fields"] = dbFunctionDatas[i].fields;
                            tempalte.Context.TempData["sqlVarParameters"] = dbFunctionDatas[i].sqlVarParameters;
                            webCsharpCode = tempalte.Render();

                            relative_position += Replace(ref csharpFileCode,
                                relative_position + dbFunctionDatas[i].index,
                                dbFunctionDatas[i].length,
                                webCsharpCode);

                        }
                        if (dbFunctionDatas[i].functionName == "Delete")
                        {
                            string fileString = null;
                            if (connectionString.type == DB.DBType.MySql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.mysql.mysql.Delete;
                            }
                            else if (connectionString.type == DB.DBType.Oracle)
                            {
                                fileString = NFinal.Compile.SqlTemplate.oracle.oracle.Delete;
                            }
                            else if (connectionString.type == DB.DBType.Sqlite)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlite.sqlite.Delete;
                            }
                            else if (connectionString.type == DB.DBType.SqlServer)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlserver.sqlserver.Delete;
                            }
                            else if(connectionString.type==DB.DBType.PostgreSql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.postgresql.postgresql.Delete;
                            }
                            tempalte = new JinianNet.JNTemplate.Template(fileString);
                            tempalte.Context.TempData["functionName"] = methodName;
                            tempalte.Context.TempData["varName"] = dbFunctionDatas[i].varName;
                            tempalte.Context.TempData["hasGenericType"] = dbFunctionDatas[i].hasGenericType;
                            tempalte.Context.TempData["type"] = dbFunctionDatas[i].type;
                            tempalte.Context.TempData["isDeclaration"] = dbFunctionDatas[i].isDeclaration;
                            tempalte.Context.TempData["connectionVarName"] = dbFunctionDatas[i].connectionVarName;
                            tempalte.Context.TempData["isTransaction"] = dbFunctionDatas[i].isTransaction;
                            tempalte.Context.TempData["transactionVarName"] = dbFunctionDatas[i].transactionVarName;
                            tempalte.Context.TempData["dbName"] = dbFunctionDatas[i].connectionName;
                            tempalte.Context.TempData["sql"] = dbFunctionDatas[i].sql;
                            tempalte.Context.TempData["fields"] = dbFunctionDatas[i].fields;
                            tempalte.Context.TempData["sqlVarParameters"] = dbFunctionDatas[i].sqlVarParameters;
                            webCsharpCode = tempalte.Render();
                            relative_position += Replace(ref csharpFileCode,
                                relative_position + dbFunctionDatas[i].index,
                                dbFunctionDatas[i].length,
                                webCsharpCode);

                        }
                        if (dbFunctionDatas[i].functionName == "QueryObject")
                        {
                            string fileString = null;
                            if (connectionString.type == DB.DBType.MySql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.mysql.mysql.QueryObject;
                            }
                            else if (connectionString.type == DB.DBType.Oracle)
                            {
                                fileString = NFinal.Compile.SqlTemplate.oracle.oracle.QueryObject;
                            }
                            else if (connectionString.type == DB.DBType.Sqlite)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlite.sqlite.QueryObject;
                            }
                            else if (connectionString.type == DB.DBType.SqlServer)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlserver.sqlserver.QueryObject;
                            }
                            else if(connectionString.type == DB.DBType.PostgreSql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.postgresql.postgresql.QueryObject;
                            }
                            tempalte = new JinianNet.JNTemplate.Template(fileString);
                            tempalte.Context.TempData["functionName"] = methodName;
                            tempalte.Context.TempData["varName"] = dbFunctionDatas[i].varName;
                            tempalte.Context.TempData["hasGenericType"] = dbFunctionDatas[i].hasGenericType;
                            tempalte.Context.TempData["type"] = dbFunctionDatas[i].type;
                            tempalte.Context.TempData["isDeclaration"] = dbFunctionDatas[i].isDeclaration;
                            tempalte.Context.TempData["connectionVarName"] = dbFunctionDatas[i].connectionVarName;
                            tempalte.Context.TempData["isTransaction"] = dbFunctionDatas[i].isTransaction;
                            tempalte.Context.TempData["transactionVarName"] = dbFunctionDatas[i].transactionVarName;
                            tempalte.Context.TempData["dbName"] = dbFunctionDatas[i].connectionName;
                            tempalte.Context.TempData["sql"] = dbFunctionDatas[i].sql;
                            tempalte.Context.TempData["fields"] = dbFunctionDatas[i].fields;
                            tempalte.Context.TempData["sqlVarParameters"] = dbFunctionDatas[i].sqlVarParameters;
                            tempalte.Context.TempData["convertMethodName"] = dbFunctionDatas[i].convertMethodName;
                            webCsharpCode = tempalte.Render();
                            relative_position += Replace(ref csharpFileCode,
                                relative_position + dbFunctionDatas[i].index,
                                dbFunctionDatas[i].length,
                                webCsharpCode);
                        }
                        if (dbFunctionDatas[i].functionName == "Page")
                        {
                            string fileString = null;
                            if (connectionString.type == DB.DBType.MySql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.mysql.mysql.Page;
                            }
                            else if (connectionString.type == DB.DBType.Oracle)
                            {
                                fileString = NFinal.Compile.SqlTemplate.oracle.oracle.Page;
                            }
                            else if (connectionString.type == DB.DBType.Sqlite)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlite.sqlite.Page;
                            }
                            else if (connectionString.type == DB.DBType.SqlServer)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlserver.sqlserver.Page;
                            }
                            else if(connectionString.type == DB.DBType.PostgreSql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.postgresql.postgresql.Page;
                            }
                            tempalte = new JinianNet.JNTemplate.Template(fileString);
                            tempalte.Context.TempData["functionName"] = methodName;
                            tempalte.Context.TempData["varName"] = dbFunctionDatas[i].varName;
                            tempalte.Context.TempData["hasGenericType"] = dbFunctionDatas[i].hasGenericType;
                            tempalte.Context.TempData["type"] = dbFunctionDatas[i].type;
                            tempalte.Context.TempData["isDeclaration"] = dbFunctionDatas[i].isDeclaration;
                            tempalte.Context.TempData["connectionVarName"] = dbFunctionDatas[i].connectionVarName;
                            tempalte.Context.TempData["isTransaction"] = dbFunctionDatas[i].isTransaction;
                            tempalte.Context.TempData["transactionVarName"] = dbFunctionDatas[i].transactionVarName;
                            tempalte.Context.TempData["dbName"] = dbFunctionDatas[i].connectionName;
                            tempalte.Context.TempData["fields"] = dbFunctionDatas[i].fields;
                            

                            //分页参数解析
                            PageSqlAnalyse pageStatement = new PageSqlAnalyse(dbFunctionDatas[i].sql,connectionString.type);
                            pageStatement.Parse();
                            tempalte.Context.TempData["pageSql"] = pageStatement.pageSql;
                            tempalte.Context.TempData["countSql"] = pageStatement.countSql;
                            tempalte.Context.TempData["pageVarName"] = dbFunctionDatas[i].parameters[1];

                            tempalte.Context.TempData["sqlVarParameters"] = dbFunctionDatas[i].sqlVarParameters;
                            tempalte.Context.TempData["convertMethodName"] = dbFunctionDatas[i].convertMethodName;
                            webCsharpCode = tempalte.Render();
                            relative_position += Replace(ref csharpFileCode,
                                relative_position + dbFunctionDatas[i].index,
                                dbFunctionDatas[i].length,
                                webCsharpCode);
                        }
                        if (dbFunctionDatas[i].functionName == "QueryRandom")
                        {
                            string fileString = null;
                            if (connectionString.type == DB.DBType.MySql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.mysql.mysql.QueryRandom;
                            }
                            else if (connectionString.type == DB.DBType.Oracle)
                            {
                                fileString = NFinal.Compile.SqlTemplate.oracle.oracle.QueryRandom;
                            }
                            else if (connectionString.type == DB.DBType.Sqlite)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlite.sqlite.QueryRandom;
                            }
                            else if (connectionString.type == DB.DBType.SqlServer)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlserver.sqlserver.QueryRandom;
                            }
                            else if (connectionString.type == DB.DBType.PostgreSql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.postgresql.postgresql.QueryRandom;
                            }
                            tempalte = new JinianNet.JNTemplate.Template(fileString);
                            tempalte.Context.TempData["functionName"] = methodName;
                            tempalte.Context.TempData["varName"] = dbFunctionDatas[i].varName;
                            tempalte.Context.TempData["hasGenericType"] = dbFunctionDatas[i].hasGenericType;
                            tempalte.Context.TempData["type"] = dbFunctionDatas[i].type;
                            tempalte.Context.TempData["isDeclaration"] = dbFunctionDatas[i].isDeclaration;
                            tempalte.Context.TempData["connectionVarName"] = dbFunctionDatas[i].connectionVarName;
                            tempalte.Context.TempData["isTransaction"] = dbFunctionDatas[i].isTransaction;
                            tempalte.Context.TempData["transactionVarName"] = dbFunctionDatas[i].transactionVarName;
                            tempalte.Context.TempData["dbName"] = dbFunctionDatas[i].connectionName;
                            //select 语句 转为选取某随机行的语句

                            RandomSqlAnalyse random = new RandomSqlAnalyse(dbFunctionDatas[i].sql, connectionString.type);
                            random.Parse();

                            tempalte.Context.TempData["topNumber"] = dbFunctionDatas[i].parameters[1];
                            tempalte.Context.TempData["sql"] = random.randomSql;
                            tempalte.Context.TempData["fields"] = dbFunctionDatas[i].fields;
                            tempalte.Context.TempData["sqlVarParameters"] = dbFunctionDatas[i].sqlVarParameters;
                            webCsharpCode = tempalte.Render();
                            relative_position += Replace(ref csharpFileCode,
                                relative_position + dbFunctionDatas[i].index,
                                dbFunctionDatas[i].length,
                                webCsharpCode);
                        }
                        if (dbFunctionDatas[i].functionName == "QueryTop")
                        {
                            string fileString = null;
                            if (connectionString.type == DB.DBType.MySql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.mysql.mysql.QueryTop;
                            }
                            else if (connectionString.type == DB.DBType.Oracle)
                            {
                                fileString = NFinal.Compile.SqlTemplate.oracle.oracle.QueryTop;
                            }
                            else if (connectionString.type == DB.DBType.Sqlite)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlite.sqlite.QueryTop;
                            }
                            else if (connectionString.type == DB.DBType.SqlServer)
                            {
                                fileString = NFinal.Compile.SqlTemplate.sqlserver.sqlserver.QueryTop;
                            }
                            else if(connectionString.type == DB.DBType.PostgreSql)
                            {
                                fileString = NFinal.Compile.SqlTemplate.postgresql.postgresql.QueryTop;
                            }
                            tempalte = new JinianNet.JNTemplate.Template(fileString);
                            tempalte.Context.TempData["functionName"] = methodName;
                            tempalte.Context.TempData["varName"] = dbFunctionDatas[i].varName;
                            tempalte.Context.TempData["hasGenericType"] = dbFunctionDatas[i].hasGenericType;
                            tempalte.Context.TempData["type"] = dbFunctionDatas[i].type;
                            tempalte.Context.TempData["isDeclaration"] = dbFunctionDatas[i].isDeclaration;
                            tempalte.Context.TempData["connectionVarName"] = dbFunctionDatas[i].connectionVarName;
                            tempalte.Context.TempData["isTransaction"] = dbFunctionDatas[i].isTransaction;
                            tempalte.Context.TempData["transactionVarName"] = dbFunctionDatas[i].transactionVarName;
                            tempalte.Context.TempData["dbName"] = dbFunctionDatas[i].connectionName;
                            //select 语句 转为选取某随机行的语句

                            TopSqlAnalyse top = new TopSqlAnalyse(dbFunctionDatas[i].sql, connectionString.type);
                            top.Parse();

                            tempalte.Context.TempData["topNumber"] = dbFunctionDatas[i].parameters[1];
                            tempalte.Context.TempData["sql"] = top.topSql;
                            tempalte.Context.TempData["fields"] = dbFunctionDatas[i].fields;
                            tempalte.Context.TempData["sqlVarParameters"] = dbFunctionDatas[i].sqlVarParameters;
                            webCsharpCode = tempalte.Render();
                            relative_position += Replace(ref csharpFileCode,
                                relative_position + dbFunctionDatas[i].index,
                                dbFunctionDatas[i].length,
                                webCsharpCode);
                        }
                    }
                }
            }
            return relative_position;
        }
        /// <summary>
        /// 数据库函数替换类
        /// </summary>
        /// <param name="methodName">函数名</param>
        /// <param name="dbFunctionData">函数信息</param>
        /// <param name="appRoot">网站根目录</param>
        /// <returns></returns>
        public string SetMagicStruct(string methodName,DbFunctionData dbFunctionData, System.Collections.Generic.List<NFinal.Compile.StructField> structFieldList,string appRoot)
        {
            string result = null;
            if (dbFunctionData.functionName == "QueryAll" || dbFunctionData.functionName == "QueryRow" 
                || dbFunctionData.functionName == "Page" || dbFunctionData.functionName == "QueryRandom"
                || dbFunctionData.functionName =="QueryTop")
            {
                DB.ConnectionString connectionString = null;
                connectionString = GetConnectionString(dbFunctionData.connectionName);

                JinianNet.JNTemplate.ITemplate template = null;
                string fileString = null;
                if (connectionString.type == DB.DBType.MySql)
                {
                    fileString = NFinal.Compile.SqlTemplate.mysql.mysql.Struct;
                }
                else if (connectionString.type == DB.DBType.Oracle)
                {
                    fileString = NFinal.Compile.SqlTemplate.oracle.oracle.Struct;
                }
                else if (connectionString.type == DB.DBType.Sqlite)
                {
                    fileString = NFinal.Compile.SqlTemplate.sqlite.sqlite.Struct;
                }
                else if (connectionString.type == DB.DBType.SqlServer)
                {
                    fileString = NFinal.Compile.SqlTemplate.sqlserver.sqlserver.Struct;
                }
                else if (connectionString.type == DB.DBType.PostgreSql)
                {
                    fileString = NFinal.Compile.SqlTemplate.postgresql.postgresql.Struct;
                }
                template = new JinianNet.JNTemplate.Template(fileString);
                template.Context.TempData["functionName"] = methodName;
                template.Context.TempData["varName"] = dbFunctionData.varName;
                template.Context.TempData["hasGenericType"] = dbFunctionData.hasGenericType;
                template.Context.TempData["type"] = dbFunctionData.type;
                template.Context.TempData["isDeclaration"] = dbFunctionData.isDeclaration;
                template.Context.TempData["connectionVarName"] = dbFunctionData.connectionVarName;
                template.Context.TempData["isTransaction"] = dbFunctionData.isTransaction;
                template.Context.TempData["transactionVarName"] = dbFunctionData.transactionVarName;
                template.Context.TempData["fields"] = dbFunctionData.fields;
                template.Context.TempData["structFields"] = structFieldList;
                result = template.Render();
            }
            return result;
        }
       
    }
}